package messages;

import java.util.Collection;
import java.util.HashMap;

public class DevMessage {
    private final HashMap<String, String> msgDict;
    private DeviceType deviceType;
    private MessageType messageType;
    private String deviceID;

    public DevMessage() {
        deviceType = DeviceType.DEVICE_TYPE_NONE;
        messageType = MessageType.MESSAGE_TYPE_NONE;
        msgDict = new HashMap<>();
    }

    static String separate(String token, String keyRequest) {
        String[] args = token.split("=");

        if (args.length != 2) {
            return null;
        }

        if (!args[0].equals(keyRequest)) {
            return null;
        }

        return args[1];
    }

    public static DevMessage create(String rawMessage) {

        DevMessage devMessage = new DevMessage();
        String[] tokens = rawMessage.split(",");

        if (tokens.length < 3) {
            return null;
        }

        if (!tokens[0].equals("zncdz")) {
            return null;
        }

        String argValue = separate(tokens[1], "devType");
        if (argValue == null) {
            return null;
        }
        switch (argValue) {
            case "EMB":
                devMessage.setDeviceType(DeviceType.DEVICE_TYPE_EMBEDDED);
                break;
            case "TERM":
                devMessage.setDeviceType(DeviceType.DEVICE_TYPE_TERMINAL);
                break;
            case "ADMIN":
                devMessage.setDeviceType(DeviceType.DEVICE_TYPE_ADMIN);
                break;
            case "BOX":
                devMessage.setDeviceType(DeviceType.DEVICE_TYPE_MEDICINE_BOX);
                break;
            case "MP":
                devMessage.setDeviceType(DeviceType.DEVICE_TYPE_MY_PHONE);
                break;
            default:
                return null;
        }

        argValue = separate(tokens[2], "msgType");
        if (argValue == null) {
            return null;
        }
        switch (argValue) {
            case "REGU":
                devMessage.setMessageType(MessageType.MESSAGE_TYPE_REG_USER);
                break;
            case "PUB":
                devMessage.setMessageType(MessageType.MESSAGE_TYPE_PUBLISH);
                break;
            case "REG":
                devMessage.setMessageType(MessageType.MESSAGE_TYPE_REGISTER);
                break;
            case "LOG":
                devMessage.setMessageType(MessageType.MESSAGE_TYPE_LOGS);
                break;
            case "SUB":
                devMessage.setMessageType(MessageType.MESSAGE_TYPE_SUBSCRIBE);
                break;
            case "CONTROL":
                if (devMessage.getDeviceType() != DeviceType.DEVICE_TYPE_ADMIN) {
                    return null;
                }
                devMessage.setMessageType(MessageType.MESSAGE_TYPE_CONTROL);
                break;
            default:
                return null;
        }

        argValue = separate(tokens[3], "devID");
        if (argValue == null) {
            return null;
        }
        devMessage.setDeviceID(argValue);

        for (int i = 4; i < tokens.length; ++i) {
            String[] args = tokens[i].split("=");
            if (args.length >= 2) {
                devMessage.setMsgDict(args[0], args[1]);
            } else if (args.length == 1) {
                devMessage.setMsgDict(args[0], "0");
            }
        }

        return devMessage;
    }

    public Collection<String> getMsgDictKeys() {
        return msgDict.keySet();
    }

    public DeviceType getDeviceType() {
        return deviceType;
    }

    public void setDeviceType(DeviceType deviceType) {
        this.deviceType = deviceType;
    }

    public String getDeviceID() {
        return deviceID;
    }

    public void setDeviceID(String deviceID) {
        this.deviceID = deviceID;
    }

    public MessageType getMessageType() {
        return messageType;
    }

    public void setMessageType(MessageType messageType) {
        this.messageType = messageType;
    }

    public HashMap<String, String> getMsgDict() {
        return this.msgDict;
    }

    public String getMsgDict(String key) {
        return this.msgDict.get(key);
    }

    private void setMsgDict(String key, String value) {
        this.msgDict.put(key, value);
    }

}
